package ext.tianma.number.util;

import java.rmi.RemoteException;
import java.util.Locale;
import java.util.Vector;

import wt.doc.WTDocument;
import wt.doc.WTDocumentMaster;
import wt.fc.ObjectVector;
import wt.fc.Persistable;
import wt.fc.PersistenceHelper;
import wt.fc.PersistenceServerHelper;
import wt.fc.QueryResult;
import wt.introspection.WTIntrospector;
import wt.part.WTPart;
import wt.part.WTPartDescribeLink;
import wt.part.WTPartHelper;
import wt.pds.StatementSpec;
import wt.pom.Transaction;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.query.WhereExpression;
import wt.util.WTContext;
import wt.util.WTException;
import wt.util.WTProperties;
import wt.util.WTPropertyVetoException;
import wt.vc.Iterated;
import wt.vc.Mastered;
import wt.vc.VersionControlHelper;
import wt.vc.config.ConfigHelper;
import wt.vc.config.ConfigSpec;
import wt.vc.config.LatestConfigSpec;
import wt.vc.wip.WorkInProgressHelper;
import wt.vc.wip.Workable;
import ext.com.iba.IBAUtil;

public class DocUtil{
	private static final String CLASSNAME = DocUtil.class.getName();
	protected static boolean VERBOSE;
	public static final String PSSTATESTR="过程开发阶段";
	static {
		try{
			WTProperties wtproperties = WTProperties.getLocalProperties();
			VERBOSE = wtproperties.getProperty("ext.tianma.number.util.verbose", false);  
		}
		catch(Throwable throwable){
			throwable.printStackTrace(System.err);
			throw new ExceptionInInitializerError(throwable);
		}
	}
     /**
      * 删除部件和文档的关联关系
      * @param wtpart
      * @param wtdocument
      * @return
      * @throws WTException
      */
	public static WTPart deletePartDocRelation(WTPart wtpart, WTDocument wtdocument)throws WTException{
		if(VERBOSE)
			System.out.println(">>>" + CLASSNAME + ".deletePartDocRelation()");
		Transaction transaction = new Transaction();
		try{
			transaction.start();
			PersistenceServerHelper.manager.lock(wtpart, true);
			QueryResult queryresult = intGetAssociations(wtpart, wtdocument);
			if(queryresult.size() > 0){
				if(VERBOSE)
					System.out.println("    delete relations.");
				for(; queryresult.hasMoreElements(); PersistenceServerHelper.manager.remove((Persistable)queryresult.nextElement()));
			}
			transaction.commit();
			transaction = null;
		}
		finally{
			if(transaction != null)
				transaction.rollback();
		}
		if(VERBOSE)
			System.out.println("<<<" + CLASSNAME + ".deletePartDocRelation()");
		return wtpart;
	}
	/**
	 * 获取部件和文档的关联关系
	 * @param wtpart
	 * @param wtdocument
	 * @return
	 * @throws WTException
	 */
	protected static QueryResult intGetAssociations(WTPart wtpart, WTDocument wtdocument)throws WTException{
		if(VERBOSE)
			System.out.println(">>>" + CLASSNAME + "intGetAssociations()");
		String s1 = null;
		String s2 = null;
		if(WTIntrospector.getLinkInfo(wt.part.WTPartReferenceLink.class).isRoleA("describedBy")){
			s1 = "roleAObjectRef.key";
			s2 = "roleBObjectRef.key";
		} 
		else{
			s2 = "roleAObjectRef.key";
			s1 = "roleBObjectRef.key";
		}
		QuerySpec queryspec1 = new QuerySpec(wt.part.WTPartDescribeLink.class);
		queryspec1.appendClassList(wt.doc.WTDocument.class, true);
		queryspec1.appendWhere(new SearchCondition(wt.part.WTPartDescribeLink.class, s2, "=", PersistenceHelper.getObjectIdentifier(wtpart)), 0, 0);
		queryspec1.appendAnd();
		queryspec1.appendWhere(new SearchCondition(wt.part.WTPartDescribeLink.class, s1 + "." + "id", wt.doc.WTDocument.class, "thePersistInfo.theObjectIdentifier.id"), 0, 1);
		queryspec1.appendAnd();
		queryspec1.appendWhere(new SearchCondition(wt.doc.WTDocument.class, "masterReference.key", "=", PersistenceHelper.getObjectIdentifier(wtdocument.getMaster())), 1, 1);
		QueryResult queryresult = PersistenceServerHelper.manager.query(queryspec1);
		ObjectVector objectvector = new ObjectVector();
		WTPartDescribeLink wtpartdescribelink;
		if(VERBOSE)
			System.out.println("    WTPartDescribeLink size=" + queryresult.size());
		for(; queryresult.hasMoreElements(); objectvector.addElement(wtpartdescribelink)){
			Object aobj[] = (Object[])queryresult.nextElement();
			wtpartdescribelink = (WTPartDescribeLink)aobj[0];
			try{
				wtpartdescribelink.setDescribes(wtpart);
				wtpartdescribelink.setDescribedBy((WTDocument)aobj[1]);
			}
			catch(WTPropertyVetoException wpve){
				throw new WTException(wpve);
			}
		}
		
		//get WTPartReferenceLink
		String s = (WTIntrospector.getLinkInfo(wt.part.WTPartReferenceLink.class).isRoleA("references") ? "roleAObjectRef" : "roleBObjectRef") + "." + "key";
		QuerySpec queryspec = new QuerySpec(wt.doc.WTDocumentMaster.class, wt.part.WTPartReferenceLink.class);
		queryspec.appendWhere(new SearchCondition(wt.part.WTPartReferenceLink.class, s, "=", PersistenceHelper.getObjectIdentifier(wtdocument.getMaster())), 1, 1);
		QueryResult queryresult2= PersistenceServerHelper.manager.expand(wtpart, "references", queryspec, false);
		if(VERBOSE)
			System.out.println("    WTPartReferenceLink size=" + queryresult2.size());
		while(queryresult2.hasMoreElements()){
			objectvector.addElement(queryresult2.nextElement());
		}
		if(VERBOSE)
			System.out.println("<<<" + CLASSNAME + "intGetAssociations()");		
		return new QueryResult(objectvector);
	}
	
	/**compare Persistable objects*/
	public static boolean comparePersistables(Persistable source, Persistable destination) throws WTException{
		return PersistenceHelper.isEquivalent(source, destination);
	}
	
	/**
	 * 判断对象是否包含在指定集合里面
	 * @param vector
	 * @param destination
	 * @return
	 * @throws WTException
	 */
	public static boolean persistableVectorContains(Vector vector, Persistable destination) throws WTException{
		if((vector==null) || (vector.size()<=0))
			return false;
		if(vector.contains(destination)){
			return true;
		}
		boolean flag= false;
		for(int i=0; i<vector.size(); i++){
			flag= comparePersistables((Persistable)vector.elementAt(i), destination);
			if(flag)
				return flag;
		}
		return flag;
	}
	/**
	 * 获取对象的最新版本
	 * @param master
	 * @return
	 * @throws WTException
	 */
	public static Iterated getLatestIteration(Mastered  master)throws WTException{
		if(VERBOSE)
			System.out.println(">>>enter getLatestIteration()");		
		Iterated iter=null; 
		boolean flag=false;
		LatestConfigSpec latestconfigspec = new LatestConfigSpec();
		QueryResult queryresult = ConfigHelper.service.filteredIterationsOf(master, latestconfigspec);      
		if(VERBOSE)
			System.out.println("    get " + queryresult.size() + " iterations for master " + master);
		while( queryresult.hasMoreElements() && (!flag) ){ 
			iter=(Iterated)(queryresult.nextElement());
			flag= iter.isLatestIteration(); 
			if(WorkInProgressHelper.isCheckedOut((Workable)iter)){
				if(!WorkInProgressHelper.isWorkingCopy((Workable)iter)){
					iter=(Iterated)WorkInProgressHelper.service.workingCopyOf((Workable)iter);
				}
			}
		}
		if(VERBOSE){
			System.out.println("    the latest iteration=" + iter);
			System.out.println("<<<out getLatestIteration()");
		}
		return iter;
	}    
	/**
	 * 判断文档的类型是否为ProcessRulesDoc
	 * @param module
	 * @return
	 * @throws WTException
	 */	
	public static boolean isProcessRulesDoc(WTDocument module)throws WTException{
		String moduleType="";
		if(module!=null){
			try{
				moduleType=wt.type.ClientTypedUtility.getExternalTypeIdentifier(module);
				if (VERBOSE)
					System.out.println("(isProcessRulesDoc) "+module.getIdentity()+";moduleType ="+moduleType);
			}catch(RemoteException re){
				throw new WTException(re);
			}
		}
		if(module!=null && moduleType.indexOf("ProcessRulesDoc")>-1){
			return true;
		}
		return false;
	}	
	
	/*
	 *判断当前文档是否为转阶段申请单	 
	 */
	public static boolean isChangeStateDoc(WTDocument module)throws WTException{
		String moduleType="";
		Locale locale= wt.session.SessionHelper.manager.getLocale();
		if(module!=null){
			try{
				moduleType=wt.type.ClientTypedUtility.getExternalTypeIdentifier(module);
			}
			catch(RemoteException re){
				throw new WTException(re);
			}
		}		
		if((module!=null) && (moduleType.indexOf("ChangeStateDoc")>=0) ){
			return true;
		}
		return false;
	}
	
	/**
	 * 
	 * @param     doc	顶层件
	 * @param     batchReviewParts	随顶层件走流程的子件的vector
	 * @exception wt.util.WTException
	 */		
	public static void getRelatedProducts(WTDocument doc, Vector relatedProducts)throws WTException,Exception{
		StringBuffer errBuf = new StringBuffer();
		Locale locale = WTContext.getContext().getLocale();		
		boolean hasValidProduct = false;
		//清空所有Vector
		if (relatedProducts!=null && relatedProducts.size()!=0)
			relatedProducts.clear();		
		Vector relatedPartsVector = getAssociatedParts(doc);
		if(relatedPartsVector!=null && relatedPartsVector.size()>0){
			for(int i=0; i<relatedPartsVector.size(); i++){
				WTPart wtpart = (WTPart)relatedPartsVector.elementAt(i);
				//判断部件是否为成品								
				if(wtpart.isEndItem()){
					String partLCState = wtpart.getLifeCycleState().toString();
					if(partLCState.equalsIgnoreCase("RELEASED")){						
						String partState = (String) IBAUtil.getIBAValue(wtpart,"CurrentState");
						if(partState.equalsIgnoreCase(PSSTATESTR)){
							hasValidProduct = true;
							relatedProducts.add(wtpart);
						}
					}
				}
			}
		}
		if(!hasValidProduct){
			errBuf.append("\n" + "文档("+ doc.getIdentity() + ")没有关联已发布而且阶段为过程开发阶段的成品！");
		}	
		if(errBuf.toString().length()>0){			
			throw new WTException(errBuf.toString());
		}
	}
	
	/**
	 *设置BOM结构的IBA属性CurrentState
	 * @param  batchReviewParts	随顶层件走流程的子件的vector
	 * @exception wt.util.WTException
	 * added by lauren on 2007-12-6
	 */		
	public static void changeRelatedProductsState(Vector relatedProducts)throws WTException,Exception{
		if(relatedProducts!=null && relatedProducts.size()>0){
			for(int i=0; i<relatedProducts.size(); i++){
				WTPart topPart = (WTPart)relatedProducts.elementAt(i);
				java.util.Hashtable table=new java.util.Hashtable();
				table.put("CurrentState", "批量生产阶段");				
				Vector subPartList = PartUtil.getSubPartListByPart(topPart,null);
				IBAUtil.setSoftTypeIBAValues(topPart,table);
				for(int j=0; j<subPartList.size(); j++){
					WTPart thisPart = (WTPart)subPartList.elementAt(j);					
					IBAUtil.setSoftTypeIBAValues(thisPart,table);					
				}
			}			
		}
	}
	
	/**
	 * 获取文档相关零件;此文档可以是描述性文档(Describes),也可以是参考性文档(Reference).
	 * @param     wtdocument 要搜索相关零件的文档
	 * @return    Vector 文档所有相关的零件 Vector
	 * @throws WTException
	 */	
	public static Vector getAssociatedParts(WTDocument wtdocument)throws WTException{
		QueryResult qr =null;
		Vector parts = new Vector();		
		//如果传入值 document==null, 直接返回空值
		if(wtdocument==null){
			return null;
		}					
		try{
			QuerySpec queryspec = new QuerySpec(wt.part.WTPart.class, wt.part.WTPartReferenceLink.class);
			queryspec.appendSearchCondition(VersionControlHelper.getSearchCondition(wt.part.WTPart.class, true), 0, 1);
			qr = PersistenceHelper.manager.navigate(wtdocument.getMaster(), "referencedBy", queryspec, true);
			while(qr.hasMoreElements()){
				WTPart part = (WTPart)qr.nextElement();
				if(!WorkInProgressHelper.isCheckedOut((Workable)part) || WorkInProgressHelper.isWorkingCopy((Workable)part))
					parts.addElement(part);
			}
			qr= WTPartHelper.service.getDescribesWTParts(wtdocument);
			while(qr.hasMoreElements()){
				WTPart part = (WTPart)qr.nextElement();
				if(!WorkInProgressHelper.isCheckedOut((Workable)part) || WorkInProgressHelper.isWorkingCopy((Workable)part))
					parts.addElement(part);    
			}
		}
		catch (WTException wte) {
			wte.printStackTrace();
		}		
		return parts;
	}
	
	/**
	 * 根据文档编号获取最新版本文档
	 * @param docNumber
	 * @return
	 * @throws WTException
	 */
	public static WTDocument getWTDocumentByNumber(String docNumber) throws WTException{	
	    WTDocument doc=null;
		try{		
			QuerySpec qs = new QuerySpec(WTDocumentMaster.class);		    			
			SearchCondition sc = new SearchCondition(WTDocumentMaster.class, "number", SearchCondition.LIKE, docNumber);		     
			qs.appendSearchCondition(sc);		    			
			QueryResult qr = PersistenceHelper.manager.find(qs);
			while(qr.hasMoreElements()){
				WTDocumentMaster master=(WTDocumentMaster)qr.nextElement();	
				doc= getLatestWTDocument(master);  
				break;
			}
		}	
		catch (WTException wte) 
		{
			wte.printStackTrace();
		}			
		return doc;
   }
	
	/**
	 * 根据文档名称获取最新版本文档
	 * @param docNumber
	 * @return
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年6月2日
	 */
	public static WTDocument getWTDocumentByName(String docNumber) throws WTException {	
	    WTDocument doc=null;
		try{		
			QuerySpec qs = new QuerySpec(WTDocumentMaster.class);		    			
			SearchCondition sc = new SearchCondition(WTDocumentMaster.class, WTDocumentMaster.NAME, SearchCondition.LIKE, docNumber);		     
			qs.appendSearchCondition(sc);		    			
			QueryResult qr = PersistenceHelper.manager.find(qs);
			while(qr.hasMoreElements()){
				WTDocumentMaster master=(WTDocumentMaster)qr.nextElement();	
				doc= getLatestWTDocument(master);  
				break;
			}
		}	
		catch (WTException wte) {
			wte.printStackTrace();
		}			
		return doc;
   }
	
	/**
	 * 该方法 根据 文档的master 获取该文档的最新小版本文档.
	 * @param     doc_master 要搜索关联的文档 master
	 * @return    WTDocument 最新小版本文档
	 * @throws WTException
	 */	     
	public static WTDocument getLatestWTDocument(WTDocumentMaster doc_master)throws WTException{
		Iterated iter=null; 
		boolean flag=false;
		LatestConfigSpec latestconfigspec = new LatestConfigSpec();
		QueryResult queryresult = ConfigHelper.service.filteredIterationsOf(doc_master, latestconfigspec);
		if(queryresult.size()<=0){
			ConfigSpec configspec = ConfigHelper.service.getDefaultConfigSpecFor(WTDocumentMaster.class);
			queryresult = ConfigHelper.service.filteredIterationsOf(doc_master, configspec);
		}		
		while( queryresult.hasMoreElements() && (!flag) ){ 
			iter=(Iterated)(queryresult.nextElement());
			flag= iter.isLatestIteration();
		}
		return (WTDocument)iter;
	}
	
}
